package com.songyang.yougnsql.core.utils;

import com.songyang.yougnsql.server.serialize.inter.YoungSqlSerialize;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * @ClassName Parser
 * @Description 解析数据工具类
 * @date 2022/12/2 14:06
 * @Author yanceysong
 * @Version 1.0
 */
public class ByteUtils {
    /**
     * short类型转byte数组
     *
     * @param value short类型的数据
     * @return byte数据
     */
    public static byte[] short2Byte(short value) {
        return ByteBuffer.allocate(Short.SIZE / Byte.SIZE).putShort(value).array();
    }
    public static byte[] EncoderType2Byte(short type){
        if (type== YoungSqlSerialize.YOUNG_SERIALIZE){
            return new byte[]{1,0};
        }else if (type==YoungSqlSerialize.KRYO_SERIALIZE){
            return new byte[]{0,1};
        }
        return new byte[]{1,0};
    }

    /**
     * byte数组解析成short
     *
     * @param buf byte数组
     * @return short类型数据
     */
    public static short parseShort(byte[] buf) {
        ByteBuffer buffer = ByteBuffer.wrap(buf, 0, 2);
        return buffer.getShort();
    }

    /**
     * 多个字节数组拼接
     *
     * @param arrays 字节数组
     * @return 拼接后的结果数组
     */
    public static byte[] concat(byte[]... arrays) {
        int length = 0;
        for (byte[] array : arrays) {
            length += array.length;
        }
        byte[] result = new byte[length];
        int pos = 0;
        for (byte[] array : arrays) {
            System.arraycopy(array, 0, result, pos, array.length);
            pos += array.length;
        }
        return result;
    }

    /**
     * int转byte数组
     *
     * @param value int 值
     * @return byte数组
     */
    public static byte[] int2Byte(int value) {
        return ByteBuffer.allocate(Integer.SIZE / Byte.SIZE).putInt(value).array();
    }

    /**
     * byte数组转int
     *
     * @param buf buf
     * @return int
     */
    public static int parseInt(byte[] buf) {
        ByteBuffer buffer = ByteBuffer.wrap(buf, 0, 4);
        return buffer.getInt();
    }

    /**
     * byte数组转long
     *
     * @param buf 原始的byte数组
     * @return long值
     */
    public static long parseLong(byte[] buf) {
        ByteBuffer buffer = ByteBuffer.wrap(buf, 0, 8);
        return buffer.getLong();
    }

    /**
     * long类型转byte
     *
     * @param value long值
     * @return byte数组
     */
    public static byte[] long2Byte(long value) {
        return ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(value).array();
    }

    /**
     * byte数组转string，从原始数组读取长度后解析
     *
     * @param raw 原始的byte数组
     * @return 转后的string
     */
    public static ParseStringRes parseString(byte[] raw) {
        int length = parseInt(Arrays.copyOf(raw, 4));
        String str = new String(Arrays.copyOfRange(raw, 4, 4 + length));
        return new ParseStringRes(str, length + 4);
    }

    /**
     * string转byte数组,最开始保留字符串的长度
     *
     * @param str str
     * @return byte数组
     */
    public static byte[] string2Byte(String str) {
        byte[] l = int2Byte(str.length());
        return ByteUtils.concat(l, str.getBytes());
    }

    /**
     * 字符串转成一个数字表示，供构建索引使用
     *
     * @param key 字符串
     * @return 转换后的数字
     */
    public static long str2Uid(String key) {
        long seed = 13331;
        long res = 0;
        for (byte b : key.getBytes()) {
            res = res * seed + (long) b;
        }
        return (res & 0x7FFFFFFF);
    }
}
